package org.yuanqiframework.yuanqi.boot.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.yuanqiframework.yuanqi.core.utils.BeanUtils;
import org.yuanqiframework.yuanqi.boot.sys.dto.SysDictDTO;
import org.yuanqiframework.yuanqi.boot.sys.dto.SysDictOptionDTO;
import org.yuanqiframework.yuanqi.boot.sys.entity.SysDict;
import org.yuanqiframework.yuanqi.boot.sys.entity.SysDictOption;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysDictMapper;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysDictOptionMapper;
import org.yuanqiframework.yuanqi.boot.sys.service.SysDictOptionService;
import org.yuanqiframework.yuanqi.boot.sys.service.SysDictService;
import org.yuanqiframework.yuanqi.boot.sys.vo.SysDictTreeOptionVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author cbt28
 * @description 针对表【sys_dict(系统字典父表)】的数据库操作Service实现
 * @createDate 2025-08-17 12:45:31
 */
@Service
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict>
        implements SysDictService {
    @Resource
    private SysDictMapper sysDictMapper;
    @Resource
    private SysDictOptionMapper sysDictOptionMapper;
    @Resource
    private SysDictOptionService sysDictOptionService;

    @Override
    public List<SysDictOption> queryListData(Long id) {
        return sysDictOptionMapper.selectList(new LambdaQueryWrapper<SysDictOption>()
                .eq(SysDictOption::getTypeId, id)
                .orderByAsc(SysDictOption::getSort));
    }

    @Override
    public List<SysDictTreeOptionVO> queryTreeData(Long id) {
        List<SysDictOption> sysDictOptions = sysDictOptionMapper.selectList(new LambdaQueryWrapper<SysDictOption>()
                .eq(SysDictOption::getTypeId, id)
                .orderByAsc(SysDictOption::getSort));
        if (sysDictOptions == null || sysDictOptions.isEmpty()) {
            return Collections.emptyList();
        }
        return queryTreeDataSub(sysDictOptions, null);
    }

    private List<SysDictTreeOptionVO> queryTreeDataSub(List<SysDictOption> sysDictOptions, Long pid) {
        if (sysDictOptions == null || sysDictOptions.isEmpty()){
            return Collections.emptyList();
        }
        List<SysDictTreeOptionVO> result = new ArrayList<>();
        sysDictOptions.stream()
                // 使用 Objects.equals 安全比较可能为 null 的值
                .filter(item -> java.util.Objects.equals(item.getParentId(), pid))
                .forEach(child -> {
                    SysDictTreeOptionVO sysDictTreeOptionVO = new SysDictTreeOptionVO();
                    sysDictTreeOptionVO.setId(child.getId());
                    sysDictTreeOptionVO.setTypeId(child.getTypeId());
                    sysDictTreeOptionVO.setLabel(child.getLabel());
                    sysDictTreeOptionVO.setValue(child.getValue());
                    sysDictTreeOptionVO.setParentId(child.getParentId());
                    sysDictTreeOptionVO.setStatus(child.getStatus());
                    sysDictTreeOptionVO.setSort(child.getSort());
                    sysDictTreeOptionVO.setChildren(queryTreeDataSub(sysDictOptions, child.getId()));
                    result.add(sysDictTreeOptionVO);
                });
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean create(SysDictDTO sysDictDTO) {
        SysDict sysDict = new SysDict();
        BeanUtils.copyProperties(sysDictDTO, sysDict);
        sysDictMapper.insert(sysDict);
        Long id = sysDict.getId();
        List<SysDictOptionDTO> children = sysDictDTO.getChildren();
        if (children != null && !children.isEmpty()) {
            List<SysDictOption> sysDictOptions = new ArrayList<>();
            for (SysDictOptionDTO child : children) {
                SysDictOption sysDictOption = new SysDictOption();
                BeanUtils.copyProperties(child, sysDictOption);
                sysDictOption.setTypeId(id);
                sysDictOptions.add(sysDictOption);
            }
            sysDictOptionService.saveBatch(sysDictOptions);
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delete(String id) {
        sysDictOptionMapper.delete(new LambdaQueryWrapper<SysDictOption>().eq(SysDictOption::getTypeId, id));
        return sysDictMapper.deleteById(id) > 0;
    }

    @Override
    public String queryTypeByCode(String code) {
        SysDict sysDict = sysDictMapper.selectOne(new LambdaQueryWrapper<SysDict>()
                .select(SysDict::getType).eq(SysDict::getCode, code));
        if (sysDict != null) {
            return sysDict.getType();
        }
        return null;
    }

    @Override
    public List<SysDictOption> queryListByCode(String code) {
        Long id = sysDictMapper.queryIdByCode(code);
        return sysDictOptionMapper.selectList(new LambdaQueryWrapper<SysDictOption>()
                .eq(SysDictOption::getTypeId, id)
                .orderByAsc(SysDictOption::getSort));
    }

    @Override
    public List<SysDictTreeOptionVO> queryTreeByCode(String code) {
        Long id = sysDictMapper.queryIdByCode(code);
        return this.queryTreeData(id);
    }
}




